package net.jgrm.product.controller;

import net.jgrm.product.service.IProductViewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 商品访问统计控制器
 * 专门用于管理和查看商品的PV/UV统计数据
 */
@RestController
@RequestMapping("/api/product-stats")
public class ProductStatsController {

    @Autowired
    private IProductViewService productViewService;

    /**
     * 手动记录商品访问（用于测试）
     */
    @PostMapping("/{productId}/record")
    public Map<String, Object> recordProductView(@PathVariable Long productId,
                                                 HttpServletRequest request,
                                                 @RequestParam(required = false) String userIdentifier) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 如果没有提供用户标识，则从请求中获取
            if (userIdentifier == null || userIdentifier.isEmpty()) {
                userIdentifier = getUserIdentifier(request);
            }

            String sessionId = request.getSession().getId();
            if (sessionId == null || sessionId.isEmpty()) {
                sessionId = UUID.randomUUID().toString();
            }

            productViewService.recordProductView(productId, userIdentifier, sessionId);

            result.put("success", true);
            result.put("message", "访问记录成功");
            result.put("productId", productId);
            result.put("userIdentifier", userIdentifier);
            result.put("sessionId", sessionId);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "访问记录失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 批量模拟访问（用于测试）
     */
    @PostMapping("/{productId}/simulate")
    public Map<String, Object> simulateProductViews(@PathVariable Long productId,
                                                    @RequestParam(defaultValue = "10") int pvCount,
                                                    @RequestParam(defaultValue = "5") int uvCount) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 模拟UV（不同用户）
            for (int i = 0; i < uvCount; i++) {
                String userIdentifier = "user_" + i + "_" + System.currentTimeMillis();
                String sessionId = "session_" + i + "_" + UUID.randomUUID().toString().substring(0, 8);
                productViewService.recordProductView(productId, userIdentifier, sessionId);
            }

            // 模拟额外的PV（重复用户访问）
            for (int i = 0; i < (pvCount - uvCount); i++) {
                String userIdentifier = "user_" + (i % uvCount) + "_" + System.currentTimeMillis();
                String sessionId = "session_extra_" + i + "_" + UUID.randomUUID().toString().substring(0, 8);
                productViewService.recordProductView(productId, userIdentifier, sessionId);
            }

            result.put("success", true);
            result.put("message", "模拟访问完成");
            result.put("productId", productId);
            result.put("simulatedPV", pvCount);
            result.put("simulatedUV", uvCount);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "模拟访问失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 获取商品访问统计详情
     */
    @GetMapping("/{productId}")
    public Map<String, Object> getProductStats(@PathVariable Long productId) {
        return productViewService.getProductViewStats(productId);
    }

    /**
     * 获取商品今日访问统计
     */
    @GetMapping("/{productId}/today")
    public Map<String, Object> getTodayStats(@PathVariable Long productId) {
        return productViewService.getTodayProductViewStats(productId);
    }

    /**
     * 获取商品PV统计
     */
    @GetMapping("/{productId}/pv")
    public Map<String, Object> getProductPV(@PathVariable Long productId) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long pv = productViewService.getProductPV(productId);
            result.put("productId", productId);
            result.put("pv", pv);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 获取商品UV统计
     */
    @GetMapping("/{productId}/uv")
    public Map<String, Object> getProductUV(@PathVariable Long productId) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long uv = productViewService.getProductUV(productId);
            result.put("productId", productId);
            result.put("uv", uv);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 批量获取商品PV统计
     */
    @PostMapping("/pv/batch")
    public Map<String, Object> getBatchPV(@RequestBody List<Long> productIds) {
        Map<String, Object> result = new HashMap<>();
        try {
            Map<Long, Long> pvMap = productViewService.getBatchProductPV(productIds.toArray(new Long[0]));
            result.put("success", true);
            result.put("data", pvMap);
            result.put("count", productIds.size());
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("success", false);
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 批量获取商品UV统计
     */
    @PostMapping("/uv/batch")
    public Map<String, Object> getBatchUV(@RequestBody List<Long> productIds) {
        Map<String, Object> result = new HashMap<>();
        try {
            Map<Long, Long> uvMap = productViewService.getBatchProductUV(productIds.toArray(new Long[0]));
            result.put("success", true);
            result.put("data", uvMap);
            result.put("count", productIds.size());
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("success", false);
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 合并指定日期的统计数据
     */
    @PostMapping("/{productId}/merge")
    public Map<String, Object> mergeStats(@PathVariable Long productId, @RequestBody List<String> dates) {
        return productViewService.mergeProductViewStats(productId, dates.toArray(new String[0]));
    }

    /**
     * 清空商品统计数据
     */
    @DeleteMapping("/{productId}")
    public Map<String, Object> clearStats(@PathVariable Long productId) {
        Map<String, Object> result = new HashMap<>();
        try {
            productViewService.clearProductViewStats(productId);
            result.put("success", true);
            result.put("message", "统计数据清空成功");
            result.put("productId", productId);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "清空失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 获取最近几天的统计数据趋势
     */
    @GetMapping("/{productId}/trend")
    public Map<String, Object> getStatsTrend(@PathVariable Long productId,
                                             @RequestParam(defaultValue = "7") int days) {
        Map<String, Object> result = new HashMap<>();
        try {
            String[] dates = new String[days];
            LocalDate today = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            for (int i = 0; i < days; i++) {
                dates[i] = today.minusDays(i).format(formatter);
            }

            Map<String, Object> mergedStats = productViewService.mergeProductViewStats(productId, dates);
            result.put("success", true);
            result.put("productId", productId);
            result.put("days", days);
            result.put("dateRange", dates);
            result.put("stats", mergedStats);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("success", false);
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 获取HyperLogLog统计信息
     */
    @GetMapping("/{productId}/hyperloglog-info")
    public Map<String, Object> getHyperLogLogInfo(@PathVariable Long productId) {
        Map<String, Object> result = new HashMap<>();
        try {
            result.put("productId", productId);
            result.put("description", "HyperLogLog是一种概率性数据结构，用于高效统计基数");

            Map<String, Object> features = new HashMap<>();
            features.put("memoryUsage", "固定12KB内存使用");
            features.put("errorRate", "标准错误率约0.81%");
            features.put("maxCardinality", "最大可统计2^64个不同元素");
            features.put("performance", "时间复杂度O(1)");
            result.put("features", features);

            Map<String, String> keyPrefixes = new HashMap<>();
            keyPrefixes.put("totalPV", "product:pv:" + productId);
            keyPrefixes.put("totalUV", "product:uv:" + productId);
            keyPrefixes.put("dailyPV", "product:daily:pv:" + productId + ":yyyy-MM-dd");
            keyPrefixes.put("dailyUV", "product:daily:uv:" + productId + ":yyyy-MM-dd");
            result.put("keyPrefixes", keyPrefixes);
            result.put("timestamp", System.currentTimeMillis());
        } catch (Exception e) {
            result.put("error", e.getMessage());
        }
        return result;
    }

    /**
     * 获取用户标识（用于UV统计）
     */
    private String getUserIdentifier(HttpServletRequest request) {
        // 优先使用真实IP
        String realIp = request.getHeader("X-Real-IP");
        if (realIp != null && !realIp.isEmpty() && !"unknown".equalsIgnoreCase(realIp)) {
            return realIp;
        }

        // 其次使用转发IP
        String forwardedFor = request.getHeader("X-Forwarded-For");
        if (forwardedFor != null && !forwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(forwardedFor)) {
            return forwardedFor.split(",")[0].trim();
        }

        // 最后使用远程地址
        String remoteAddr = request.getRemoteAddr();
        if (remoteAddr != null && !remoteAddr.isEmpty()) {
            return remoteAddr;
        }

        // 如果都获取不到，使用随机标识
        return "unknown_" + UUID.randomUUID().toString().substring(0, 8);
    }
}